本文共 5728 字,大约阅读时间需要 19 分钟。
查看专栏其它文章:
本人是个新手,写下博客用于自我复习、自我总结。 如有错误之处,请各位大佬指出。 学习资料来源于:尚硅谷
在之前的文章中已经介绍过这部分用法,想要回顾可参照我的第 ④ 篇文章,如果对具体AJAX的用法不熟悉,可以参考文章:
因为推荐使用 axios,所以这里只用 axios 进行演示。在项目中使用的用法和之前相同。只不过需要注意,不要忘记在项目中先导入 axios:npm i axios --save
本次代码实现的功能如下图: ( 划分组件 )
根据划分组件,创建项目结构:(为方便已经简化,更具体的可参考我的第 ⑤ 篇文章) app 依然为根组件。index.js
import React from 'react'import ReactDOM from 'react-dom'import App from './components/app'import './index.css'ReactDOM.render(, document.getElementById('root'))
app.jsx
import React from 'react'import Search from './search'import UserList from './user-list'export default class App extends React.Component { state = { searchName: '' } refreshName = (searchName) => this.setState({ searchName}) render() { return () }}Search Github Users
search.jsx
/** * 上部的搜索模块 */import React, { Component} from 'react'import PropTypes from 'prop-types'class Search extends Component { static propTypes = { refreshName: PropTypes.func.isRequired } search = () => { const name = this.nameInput.value.trim() if(name){ this.props.refreshName(name) } } render() { return (this.nameInput = input)}/>) }}export default Search
user-list.jsx
/** * 下部的用户列表模块 */import React from 'react'import PropTypes from 'prop-types'import axios from 'axios'class UserList extends React.Component { static propTypes = { searchName: PropTypes.string.isRequired } state = { firstView: true, loading: false, users: null, error: null } componentWillReceiveProps(nextProps) { let searchName = nextProps.searchName console.log('发送ajax请求', searchName) const url = `https://api.github.com/search/users?q=${ searchName}` this.setState({ firstView: false, loading: true }) // 使用axios库 axios.get(url) .then((response) => { console.log(response) this.setState({ loading: false, users: response.data.items }) }) .catch((error)=>{ // debugger console.log('error', error.response.data.message, error.message) this.setState({ loading: false, error: error.message }) }) } render () { if (this.state.firstView) { returnEnter name to search
} else if (this.state.loading) { returnLoading result...
} else if (this.state.error) { return{ this.state.error}
} else { return ( ) } }}export default UserList
在这里使用到了之前在生命周期中提到过的,componentWillReceiveProps()
。这个勾子函数的使用也是比较频繁的,它的作用是:组件将要接收到新的props时回调。而在上面代码的整个过程中,只要从输入框中输入新数据搜索信息时,就会将该搜索内容通过props的方式传递给该组件,因此将axios请求放在其中,就是十分合适的。
对于第一种方式应该已经不陌生了,在这里就不放代码了。测试语法时,所有组件传递用的都是 props。那在项目中,我们通常将共同的数据放在父组件上,特有的数据放在各自组件内部 (state)。然后涉及到数据传递,用的就是 props。
从目前来看,它的特点是:可以传递一般数据和函数数据,且只能一层一层传递。
对于这种方式,想要使用需要下载: npm install pubsub-js --save
它的使用方法:
import PubSub from 'pubsub-js' //引入PubSub.subscribe('delete', function(data){ }); //订阅PubSub.publish('delete', data) //发布消息
它和 props 那种需要一层一层传递的区别是:消息订阅-发布的方式可以做到直接传递
接下来的演示代码将对上面AJAX部分的代码进行修改。
首先对于 app.jsx,之前的时候我们把共同的数据存放在父组件上,这样才能做到数据传递。但现在有了 消息订阅-发布的方式,我们已经不需要这么做了,现在可以做到直接传递:
import React from 'react'import Search from './search'import UserList from './user-list'export default class App extends React.Component { render() { return () }}Search Github Users
然后对于搜索框组件 search.jsx,我们要将输入的数据传递给用户列表组件,去使用 axios 获取数据,此时我们只需 发布消息 即可。需要注意的是,消息名要和订阅消息时的消息名相同,比如在这里是 search
。传递的消息是 searchName。
/** * 上部的搜索模块 */import React, { Component} from 'react'import PubSub from 'pubsub-js'class Search extends Component { search = () => { const searchName= this.nameInput.value.trim() if(searchName){ //发布消息 PubSub.publish('search', searchName) } } render() { return (this.nameInput = input)}/>) }}export default Search
因此,根据上述内容,订阅消息时其消息名一定要为 search
才能匹配。这里的msg不用管,其实代表的是消息名。在这里接收传递过来消息的参数名是 searchName。但这个参数名,不一定要和发布消息时的相同。
/** * 下部的用户列表模块 */import React from 'react'import axios from 'axios'import PubSub from 'pubsub-js'class UserList extends React.Component { state = { firstView: true, loading: false, users: null, error: null } componentDidMount() { //订阅消息 PubSub.subscribe('search',(msg,searchName) => { const url = `https://api.github.com/search/users?q=${ searchName}` this.setState({ firstView: false, loading: true }) // 使用axios库 axios.get(url).then((response) => { this.setState({ loading: false, users: response.data.items }) }).catch((error)=>{ this.setState({ loading: false, error: error.message }) }) }) } render () { if (this.state.firstView) { returnEnter name to search
} else if (this.state.loading) { returnLoading result...
} else if (this.state.error) { return{ this.state.error}
} else { return ( ) } }}export default UserList
转载地址:http://rmyki.baihongyu.com/